Overall Objective

Load Libraries

library(tidyverse)
library(cowplot)
library(broom)
library(pwr)
library(plotly)

Import data

#setwd("~/GitHub/time-course/data")
setwd("~/Library/Mobile\ Documents/com~apple~CloudDocs/time-course/data")
rawdata <- "revised_MASTER-ExperimentSummary.csv"
timecourse <- "timecourse2017.csv"
data <- read_csv(rawdata)
tc <- read_csv(timecourse, na = c("","NA"))

Convert data from ‘wide’ to ‘long’ format

data1 <- data %>%
  gather(Sample,Count,2:250)
# Separate samples by identifiers 
data2 <- data1 %>% 
  separate(Sample, into=c("Sample_ID","Dilution_factor","Injection","Tech_rep", sep = "_")) %>% 
  select(-`_`)

Factor the data into categorical variables

# Refactoring Columns for samples
data2$Sample_ID <- as.factor(data2$Sample_ID)
data2$Dilution_factor <- as.numeric(data2$Dilution_factor)
data2$Injection<- as.factor(data2$Injection)
data2$Tech_rep <- as.numeric(data2$Tech_rep)
# Refactoring COlumns for timecourse
tc$Sample_ID <- as.factor(tc$Sample_ID)
tc$Day <- as.factor(tc$Day)
tc$Weight <- as.numeric(tc$Weight)
tc$TEI_Day <- as.factor(tc$TEI_Day)
tc1 <- tc %>% 
  select(Day:Pups)
tc1

Back calculate the original concentration of the sample

data2 <- data2 %>% 
  mutate(True_Count=Dilution_factor*Count)
data2

Average the three technical replicate readings

data3 <- data2 %>% 
  group_by(particle_size,Sample_ID,Dilution_factor,Injection) %>% 
  summarise( tech_N = length(True_Count),
             tech_mean = mean(True_Count),
             tech_sd = sd(True_Count),
             tech_se = tech_sd/sqrt(tech_N))
data3
test1 <- left_join(tc1,data3, by= "Sample_ID")

Summarize samples by injection (average both injections)

data4 <- data3 %>% 
  group_by(particle_size,Sample_ID,Dilution_factor) %>% 
  summarise( inj_N = length(tech_mean),
             inj_mean = mean(tech_mean),
             inj_sd = sd(tech_mean),
             inj_se = inj_sd/sqrt(inj_N))
data4
test2 <- left_join(tc1,data4, by= "Sample_ID")
test2

Quick visualizations

Graphing all samples

test1$Sample_ID_correct = factor(test1$Sample_ID, levels=c('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','70','73','74','75'))
graph1 <- test1 %>%
  ggplot(aes(x=particle_size, y=tech_mean,color=Injection ))+ #plot
  geom_ribbon(aes(ymin=tech_mean-tech_se, ymax=tech_mean+tech_se),alpha=0.2,fill = alpha('grey12', 0.2)) + #error bars
  geom_line(size=2.0) + xlim(0,500)+ #line size, x-axis scale
  scale_y_continuous(expand=c(0,0))+ #set bottom of graph
  xlab("Particle Size") + # X axis label
  ylab("\nMean Particle Concentration/ml\n") + # Y axis label
  ggtitle("Nanosight Histogram of\nVirgin Mouse Plasma")+ #title
  labs(color="Injection")+ #Label table title
  facet_wrap( ~ Sample_ID_correct, nrow=7)
graph1

Graphing averaged samples by experimental day

graph2 <- test2 %>%
  group_by(TEI_Day) %>% 
  ggplot(aes(x=particle_size, y=inj_mean,color=Day ))+ #plot
  #geom_ribbon(aes(ymin=inj_mean-inj_se, ymax=inj_mean+inj_se),alpha=0.2,fill = alpha('grey12', 0.2)) + #error bars
  geom_line(size=2) + xlim(0,500)+ #line size, x-axis scale
  scale_y_continuous(expand=c(0,0))+ #set bottom of graph
  xlab("Particle Size") + # X axis label
  ylab("\nMean Particle Concentration/ml\n") + # Y axis label
  ggtitle("Nanosight Histogram of\nVirgin Mouse Plasma")+ #title
  labs(color="Condition")+ #Label table title
  facet_wrap(~ TEI_Day, ncol=7)
graph2

Particle concentration values for each of the 36 samples

test3 <- test2 %>% 
  group_by(Day,Sample_ID) %>% 
  summarise(particle_conc=sum(inj_mean))
test3

Summary statistics of particle concentration (averaging n=6 for each time point)

test4 <- test3 %>% 
  group_by(Day) %>% 
  summarise(Day_N=length(particle_conc),
            Day_mean = mean(particle_conc),
            Day_sd = sd(particle_conc),
            Day_se = Day_sd/sqrt(Day_N))
test4

Boxplot

plot1 <- test3 %>% 
  filter(!Sample_ID %in% c('6','28','32')) %>% 
  group_by(Day) %>% 
  ggplot(aes(x= Day, y = particle_conc, color=Day)) +
  geom_boxplot(colour="black",fill=NA) + 
  geom_point(aes(text = paste("Sample ID:", Sample_ID)),
             position='jitter',size=3)+
  xlab("\nDay of Gestation\n") + # X axis label
  ylab("\nExosomes/ml\n") + # Y axis label
  ggtitle("Plasma Exosome Concentration\nThroughout Pregnancy\n")+ #title
  labs(color="Condition")+ # Label table title
  scale_x_discrete(breaks=c("1","5","10","14","17","20"),  # Change X axis label
                   labels=c("Virgin","5","10","14","17","1 Day Post")) +
  scale_color_discrete(labels=c("Virgin","5","10","14","17","1 Day Post")) # Change Legend
  
plot1

#ggsave("Exosome_plot.png", height = 5, width = 7, units = "in", dpi = 600)

Plotly

  ggplotly(plot1)

Bar plot

Looking at Variation between the days the samples were run

test7 <- test3 %>% 
  left_join(tc1)
Joining, by = c("Day", "Sample_ID")
plot2 <- test7 %>%
  ggplot(aes(x = Day, y = particle_conc, color = Day, shape=TEI_Day))+
  geom_point(position= 'dodge',size=4)+
  scale_shape_manual(values=c(15,16,17,18,22,23,24))+
  xlab("\nDay of Gestation\n") + # X axis label
  ylab("\nExosomes/ml\n") + # Y axis label
  ggtitle("Plasma Exosome Concentration\nThroughout Pregnancy\n")+ #title
  labs(color="Condition") + # Label table title
  scale_x_discrete(breaks=c("1","5","10","14","17","20"),  # Change X axis label
                   labels=c("Virgin","5","10","14","17","1 Day Post")) +
  scale_color_discrete(labels=c("Virgin","5","10","14","17","1 Day Post"))
plot2

ggplotly(plot2)
Width not defined. Set with `position_dodge(width = ?)`

Looking at nanoparticle range

nano_100 <- data4 %>% 
  filter(particle_size<140.5)
nano_100_data <- left_join(tc1,nano_100, by= "Sample_ID")
nano_100_data_plot <- nano_100_data %>%
  group_by(Day,Sample_ID) %>% 
  summarise(particle_conc=sum(inj_mean)) %>% 
  filter(!Sample_ID %in% c('6','28','32')) %>% 
  ggplot(aes(factor(Day),particle_conc, color=Day)) +
  geom_boxplot(colour="black",fill=NA) + 
  geom_point(position='jitter',size=3)+
  xlab("\nDay of Gestation\n") + # X axis label
  ylab("\nExosomes/ml\n") + # Y axis label
  ggtitle("Plasma Exosome Concentration\nThroughout Pregnancy\n")+ #title
  labs(color="Condition") + # Label table title
  scale_x_discrete(breaks=c("1","5","10","14","17","20"),  # Change X axis label
                   labels=c("Virgin","5","10","14","17","1 Day Post")) +
  scale_color_discrete(labels=c("Virgin","5","10","14","17","1 Day Post"))
nano_100_data_plot   

NA

Statistics

Shapiro test

tidy(shapiro.test(test3$particle_conc))

p value >0.05 therefore conlude data is normally distributed

ANOVA

jacob <- nano_100_data %>%
   group_by(Day,Sample_ID) %>% 
  summarise(particle_conc=sum(inj_mean)) %>% 
  filter(!Sample_ID %in% c('6','28','32'))
         
fit <- aov(particle_conc ~ Day, data=jacob)
stats <- tidy(fit)
stats

Statistically significant, thus Tukey’s HSD post hoc analysis can determine significant differences.

Tukey Post Hoc Test

HSD <- TukeyHSD(fit)
tukey <- tidy(HSD)
tukey

Significant Tukey Post Hoc Test Values

tukey %>%
  filter(adj.p.value<0.05) %>% 
  arrange(adj.p.value)
test8 <- test7 %>% 
  filter(!Day == "20")
fit <- lm(particle_conc ~ Weight ,data = test8)
summary(fit)

Call:
lm(formula = particle_conc ~ Weight, data = test8)

Residuals:
       Min         1Q     Median         3Q        Max 
-2.600e+11 -7.122e+10 -2.456e+10  8.690e+10  2.239e+11 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)   
(Intercept) 5.768e+10  7.666e+10   0.752  0.45727   
Weight      8.548e+09  2.849e+09   3.000  0.00519 **
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 1.127e+11 on 32 degrees of freedom
Multiple R-squared:  0.2196,    Adjusted R-squared:  0.1952 
F-statistic: 9.002 on 1 and 32 DF,  p-value: 0.00519
tidy(summary(fit))
test7 %>% 
  ggplot(aes(x= Weight, y = particle_conc))+
  geom_point()+
  geom_smooth()+
  xlab("\nWeight (g)\n") + # X axis label
  ylab("Exosomes/ml\n") + # Y axis label
  ggtitle("Linear Regression of Exosome \nConcentration vs. Weight")+ #title
  labs(color="Day")#Label table title

NA
test7 %>% 
  filter(!Sample_ID == '70') %>% 
  ggplot(aes(x= Weight, y = particle_conc))+
  geom_point(size = 3,aes(color=factor(Day)))+
  geom_smooth(method = "lm", level = 0.95)+
  xlab("\nWeight (g)\n") + # X axis label
  ylab("Exosomes/ml\n") + # Y axis label
  ggtitle("Linear Regression of Exosome \nConcentration vs. Weight")+ #title
  labs(color="Day")#Label table title

test7 %>% 
  ggplot(aes(x= Pups, y = particle_conc))+
  geom_point(size = 4, aes(color=factor(Day)))+
  #geom_smooth(method = "lm", level = 0.95)+
  scale_x_continuous(breaks=seq(0,12,2))+
  xlab("\nNumbwe of Pups\n") + # X axis label
  ylab("Exosomes/ml\n") + # Y axis label
  ggtitle("Linear Regression of Exosome \nConcentration vs. Number of Pups")+ #title
  labs(color="Day")#Label table title

mean_placenta <- tc %>% 
  filter(Day %in% c('10','14','17') & !Sample_ID %in% c('70','73','74','75')) %>%
  select(-(TEI_Day:Pup_right),-Resorp) %>% 
  gather("Placenta_avg","Plac_weight", 3:5) %>%
  group_by(Day,Sample_ID) %>% 
  summarise(N = length(Plac_weight),
            mean_plac = mean(Plac_weight*1000, na.rm = TRUE), #convert g to mg
            sd = sd(Plac_weight)*1000,  #convert g to mg
            se = sd/sqrt(N))
mean_placenta %>% 
  inner_join(test7) %>% 
  ggplot(aes(x= mean_plac, y = particle_conc))+
  geom_point(size= 3,aes(color=factor(Day)))+
  geom_smooth(method = "lm", level = 0.95)+
  xlab("\nPlacental Weight (mg)\n") + # X axis label
  ylab("\nExosomes/ml\n") + # Y axis label
  ggtitle("Plasma Exosome Concentration\nThroughout Pregnancy\n")+ #title
  labs(color="G.D.")#Label table title
Joining, by = c("Day", "Sample_ID")
joining factor and character vector, coercing into character vector

mean_placenta %>% 
  inner_join(test7) %>% 
  ggplot(aes(x = Pups, y = particle_conc))+
  geom_point(size= 3,aes(color=factor(Day)))+
  geom_smooth(method = "lm", se= FALSE)+
  facet_wrap(~Day)+
  scale_x_continuous(breaks=seq(1,12,2))+
  xlab("\nNumbr of Pups\n") + # X axis label
  ylab("\nExosomes/ml\n") + # Y axis label
  ggtitle("Plasma Exosome Concentration\nThroughout Pregnancy\n")+ #title
  labs(color="G.D.")#Label table title
Joining, by = c("Day", "Sample_ID")
joining factor and character vector, coercing into character vector

test3 %>% 
  filter(!Day %in% c('1','20')) %>% 
  group_by(Day) %>% 
  ggplot(aes(factor(Day),particle_conc, color=Day)) +
  geom_point(size=3)+
  xlab("\nDay of Gestation\n") + # X axis label
  ylab("\nExosomes/ml\n") + # Y axis label
  ggtitle("Plasma Exosome Concentration\nThroughout Pregnancy\n")+ #title
  labs(color="Condition")#Label table title

nanosight_plot <- test1 %>%
  filter(Sample_ID == '75') %>% 
  ggplot(aes(x=particle_size, y=tech_mean,color=Injection ))+ #plot
  geom_ribbon(aes(ymin=tech_mean-tech_se, ymax=tech_mean+tech_se),alpha=0.2,fill = alpha('grey12', 0.2)) + #error bars
  geom_line(size=1.0) + xlim(0,500)+ #line size, x-axis scale
  scale_y_continuous(expand=c(0,0))+ #set bottom of graph
  xlab("Particle Size (nm)") + # X axis label
  ylab("\nMean Particle Concentration/ml\n") + # Y axis label
  ggtitle("Nanosight Histogram of\nVirgin Mouse Plasma")+ #title
  labs(color="Injection")+ #Label table title
  facet_wrap( ~Injection)
nanosight_plot
ggsave("Nanosight_plot.png", height = 5, width = 7, units = "in", dpi = 600)

LS0tCnRpdGxlOiAiTmFub3NpZ2h0IEFuYWx5c2lzIgphdXRob3I6ICJTZWFuIE5ndXllbiIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6IGRlZmF1bHQKICBodG1sX25vdGVib29rOiBkZWZhdWx0CiAgcGRmX2RvY3VtZW50OiBkZWZhdWx0Ci0tLQojT3ZlcmFsbCBPYmplY3RpdmUKCgoKIyNMb2FkIExpYnJhcmllcwoKYGBge3IsIGVjaG89VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoY293cGxvdCkKbGlicmFyeShicm9vbSkKbGlicmFyeShwd3IpCmxpYnJhcnkocGxvdGx5KQpgYGAKCiMjSW1wb3J0IGRhdGEKYGBge3IsIGVjaG89VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KI3NldHdkKCJ+L0dpdEh1Yi90aW1lLWNvdXJzZS9kYXRhIikKc2V0d2QoIn4vTGlicmFyeS9Nb2JpbGVcIERvY3VtZW50cy9jb21+YXBwbGV+Q2xvdWREb2NzL3RpbWUtY291cnNlL2RhdGEiKQoKcmF3ZGF0YSA8LSAicmV2aXNlZF9NQVNURVItRXhwZXJpbWVudFN1bW1hcnkuY3N2Igp0aW1lY291cnNlIDwtICJ0aW1lY291cnNlMjAxNy5jc3YiCgoKZGF0YSA8LSByZWFkX2NzdihyYXdkYXRhKQp0YyA8LSByZWFkX2Nzdih0aW1lY291cnNlLCBuYSA9IGMoIiIsIk5BIikpCmBgYAoKIyNDb252ZXJ0IGRhdGEgZnJvbSAnd2lkZScgdG8gJ2xvbmcnIGZvcm1hdApgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KZGF0YTEgPC0gZGF0YSAlPiUKICBnYXRoZXIoU2FtcGxlLENvdW50LDI6MjUwKQoKIyBTZXBhcmF0ZSBzYW1wbGVzIGJ5IGlkZW50aWZpZXJzIApkYXRhMiA8LSBkYXRhMSAlPiUgCiAgc2VwYXJhdGUoU2FtcGxlLCBpbnRvPWMoIlNhbXBsZV9JRCIsIkRpbHV0aW9uX2ZhY3RvciIsIkluamVjdGlvbiIsIlRlY2hfcmVwIiwgc2VwID0gIl8iKSkgJT4lIAogIHNlbGVjdCgtYF9gKQpgYGAKCiMjRmFjdG9yIHRoZSBkYXRhIGludG8gY2F0ZWdvcmljYWwgdmFyaWFibGVzCgpgYGB7cn0KIyBSZWZhY3RvcmluZyBDb2x1bW5zIGZvciBzYW1wbGVzCmRhdGEyJFNhbXBsZV9JRCA8LSBhcy5mYWN0b3IoZGF0YTIkU2FtcGxlX0lEKQpkYXRhMiREaWx1dGlvbl9mYWN0b3IgPC0gYXMubnVtZXJpYyhkYXRhMiREaWx1dGlvbl9mYWN0b3IpCmRhdGEyJEluamVjdGlvbjwtIGFzLmZhY3RvcihkYXRhMiRJbmplY3Rpb24pCmRhdGEyJFRlY2hfcmVwIDwtIGFzLm51bWVyaWMoZGF0YTIkVGVjaF9yZXApCgoKIyBSZWZhY3RvcmluZyBDT2x1bW5zIGZvciB0aW1lY291cnNlCnRjJFNhbXBsZV9JRCA8LSBhcy5mYWN0b3IodGMkU2FtcGxlX0lEKQp0YyREYXkgPC0gYXMuZmFjdG9yKHRjJERheSkKdGMkV2VpZ2h0IDwtIGFzLm51bWVyaWModGMkV2VpZ2h0KQp0YyRURUlfRGF5IDwtIGFzLmZhY3Rvcih0YyRURUlfRGF5KQpgYGAKCgpgYGB7cn0KdGMxIDwtIHRjICU+JSAKICBzZWxlY3QoRGF5OlB1cHMpCnRjMQpgYGAKCiMjQmFjayBjYWxjdWxhdGUgdGhlIG9yaWdpbmFsIGNvbmNlbnRyYXRpb24gb2YgdGhlIHNhbXBsZQpgYGB7cn0KZGF0YTIgPC0gZGF0YTIgJT4lIAogIG11dGF0ZShUcnVlX0NvdW50PURpbHV0aW9uX2ZhY3RvcipDb3VudCkKZGF0YTIKYGBgCgojIyBBdmVyYWdlIHRoZSB0aHJlZSB0ZWNobmljYWwgcmVwbGljYXRlIHJlYWRpbmdzCmBgYHtyLCBtZXNzYWdlPVRSVUUsIHdhcm5pbmc9RkFMU0V9CmRhdGEzIDwtIGRhdGEyICU+JSAKICBncm91cF9ieShwYXJ0aWNsZV9zaXplLFNhbXBsZV9JRCxEaWx1dGlvbl9mYWN0b3IsSW5qZWN0aW9uKSAlPiUgCiAgc3VtbWFyaXNlKCB0ZWNoX04gPSBsZW5ndGgoVHJ1ZV9Db3VudCksCiAgICAgICAgICAgICB0ZWNoX21lYW4gPSBtZWFuKFRydWVfQ291bnQpLAogICAgICAgICAgICAgdGVjaF9zZCA9IHNkKFRydWVfQ291bnQpLAogICAgICAgICAgICAgdGVjaF9zZSA9IHRlY2hfc2Qvc3FydCh0ZWNoX04pKQpkYXRhMwoKCnRlc3QxIDwtIGxlZnRfam9pbih0YzEsZGF0YTMsIGJ5PSAiU2FtcGxlX0lEIikKYGBgCgoKIyNTdW1tYXJpemUgc2FtcGxlcyBieSBpbmplY3Rpb24gKGF2ZXJhZ2UgYm90aCBpbmplY3Rpb25zKQpgYGB7ciwgd2FybmluZz1GQUxTRX0KCmRhdGE0IDwtIGRhdGEzICU+JSAKICBncm91cF9ieShwYXJ0aWNsZV9zaXplLFNhbXBsZV9JRCxEaWx1dGlvbl9mYWN0b3IpICU+JSAKICBzdW1tYXJpc2UoIGlual9OID0gbGVuZ3RoKHRlY2hfbWVhbiksCiAgICAgICAgICAgICBpbmpfbWVhbiA9IG1lYW4odGVjaF9tZWFuKSwKICAgICAgICAgICAgIGlual9zZCA9IHNkKHRlY2hfbWVhbiksCiAgICAgICAgICAgICBpbmpfc2UgPSBpbmpfc2Qvc3FydChpbmpfTikpCmRhdGE0Cgp0ZXN0MiA8LSBsZWZ0X2pvaW4odGMxLGRhdGE0LCBieT0gIlNhbXBsZV9JRCIpCgp0ZXN0MgoKYGBgCgojUXVpY2sgdmlzdWFsaXphdGlvbnMKCiMjIyBHcmFwaGluZyBhbGwgc2FtcGxlcwpgYGB7ciwgd2FybmluZz1GQUxTRX0KdGVzdDEkU2FtcGxlX0lEX2NvcnJlY3QgPSBmYWN0b3IodGVzdDEkU2FtcGxlX0lELCBsZXZlbHM9YygnMScsJzInLCczJywnNCcsJzUnLCc2JywnNycsJzgnLCc5JywnMTAnLCcxMScsJzEyJywnMTMnLCcxNCcsJzE1JywnMTYnLCcxNycsJzE4JywnMTknLCcyMCcsJzIxJywnMjInLCcyMycsJzI0JywnMjUnLCcyNicsJzI3JywnMjgnLCcyOScsJzMwJywnMzEnLCczMicsJzMzJywnMzQnLCczNScsJzM2JywnNzAnLCc3MycsJzc0JywnNzUnKSkKCmdyYXBoMSA8LSB0ZXN0MSAlPiUKICBnZ3Bsb3QoYWVzKHg9cGFydGljbGVfc2l6ZSwgeT10ZWNoX21lYW4sY29sb3I9SW5qZWN0aW9uICkpKyAjcGxvdAogIGdlb21fcmliYm9uKGFlcyh5bWluPXRlY2hfbWVhbi10ZWNoX3NlLCB5bWF4PXRlY2hfbWVhbit0ZWNoX3NlKSxhbHBoYT0wLjIsZmlsbCA9IGFscGhhKCdncmV5MTInLCAwLjIpKSArICNlcnJvciBiYXJzCiAgZ2VvbV9saW5lKHNpemU9Mi4wKSArIHhsaW0oMCw1MDApKyAjbGluZSBzaXplLCB4LWF4aXMgc2NhbGUKICBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kPWMoMCwwKSkrICNzZXQgYm90dG9tIG9mIGdyYXBoCiAgeGxhYigiUGFydGljbGUgU2l6ZSIpICsgIyBYIGF4aXMgbGFiZWwKICB5bGFiKCJcbk1lYW4gUGFydGljbGUgQ29uY2VudHJhdGlvbi9tbFxuIikgKyAjIFkgYXhpcyBsYWJlbAogIGdndGl0bGUoIk5hbm9zaWdodCBIaXN0b2dyYW0gb2ZcblZpcmdpbiBNb3VzZSBQbGFzbWEiKSsgI3RpdGxlCiAgbGFicyhjb2xvcj0iSW5qZWN0aW9uIikrICNMYWJlbCB0YWJsZSB0aXRsZQogIGZhY2V0X3dyYXAoIH4gU2FtcGxlX0lEX2NvcnJlY3QsIG5yb3c9NykKCmdyYXBoMQpgYGAKCgoKIyMjIEdyYXBoaW5nIGF2ZXJhZ2VkIHNhbXBsZXMgYnkgZXhwZXJpbWVudGFsIGRheQpgYGB7ciwgd2FybmluZz1GQUxTRX0KZ3JhcGgyIDwtIHRlc3QyICU+JQogIGdyb3VwX2J5KFRFSV9EYXkpICU+JSAKICBnZ3Bsb3QoYWVzKHg9cGFydGljbGVfc2l6ZSwgeT1pbmpfbWVhbixjb2xvcj1EYXkgKSkrICNwbG90CiAgI2dlb21fcmliYm9uKGFlcyh5bWluPWlual9tZWFuLWlual9zZSwgeW1heD1pbmpfbWVhbitpbmpfc2UpLGFscGhhPTAuMixmaWxsID0gYWxwaGEoJ2dyZXkxMicsIDAuMikpICsgI2Vycm9yIGJhcnMKICBnZW9tX2xpbmUoc2l6ZT0yKSArIHhsaW0oMCw1MDApKyAjbGluZSBzaXplLCB4LWF4aXMgc2NhbGUKICBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kPWMoMCwwKSkrICNzZXQgYm90dG9tIG9mIGdyYXBoCiAgeGxhYigiUGFydGljbGUgU2l6ZSIpICsgIyBYIGF4aXMgbGFiZWwKICB5bGFiKCJcbk1lYW4gUGFydGljbGUgQ29uY2VudHJhdGlvbi9tbFxuIikgKyAjIFkgYXhpcyBsYWJlbAogIGdndGl0bGUoIk5hbm9zaWdodCBIaXN0b2dyYW0gb2ZcblZpcmdpbiBNb3VzZSBQbGFzbWEiKSsgI3RpdGxlCiAgbGFicyhjb2xvcj0iQ29uZGl0aW9uIikrICNMYWJlbCB0YWJsZSB0aXRsZQogIGZhY2V0X3dyYXAofiBURUlfRGF5LCBuY29sPTcpCgpncmFwaDIKYGBgCiMjIyBQYXJ0aWNsZSBjb25jZW50cmF0aW9uIHZhbHVlcyBmb3IgZWFjaCBvZiB0aGUgMzYgc2FtcGxlcwpgYGB7cn0KdGVzdDMgPC0gdGVzdDIgJT4lIAogIGdyb3VwX2J5KERheSxTYW1wbGVfSUQpICU+JSAKICBzdW1tYXJpc2UocGFydGljbGVfY29uYz1zdW0oaW5qX21lYW4pKQp0ZXN0MwpgYGAKIyMjIFN1bW1hcnkgc3RhdGlzdGljcyBvZiBwYXJ0aWNsZSBjb25jZW50cmF0aW9uIChhdmVyYWdpbmcgbj02IGZvciBlYWNoIHRpbWUgcG9pbnQpCmBgYHtyfQp0ZXN0NCA8LSB0ZXN0MyAlPiUgCiAgZ3JvdXBfYnkoRGF5KSAlPiUgCiAgc3VtbWFyaXNlKERheV9OPWxlbmd0aChwYXJ0aWNsZV9jb25jKSwKICAgICAgICAgICAgRGF5X21lYW4gPSBtZWFuKHBhcnRpY2xlX2NvbmMpLAogICAgICAgICAgICBEYXlfc2QgPSBzZChwYXJ0aWNsZV9jb25jKSwKICAgICAgICAgICAgRGF5X3NlID0gRGF5X3NkL3NxcnQoRGF5X04pKQp0ZXN0NApgYGAKCiMjI0JveHBsb3QKYGBge3IsIHdhcm5pbmc9RkFMU0V9CnBsb3QxIDwtIHRlc3QzICU+JSAKICBmaWx0ZXIoIVNhbXBsZV9JRCAlaW4lIGMoJzYnLCcyOCcsJzMyJykpICU+JSAKICBncm91cF9ieShEYXkpICU+JSAKICBnZ3Bsb3QoYWVzKHg9IERheSwgeSA9IHBhcnRpY2xlX2NvbmMsIGNvbG9yPURheSkpICsKICBnZW9tX2JveHBsb3QoY29sb3VyPSJibGFjayIsZmlsbD1OQSkgKyAKICBnZW9tX3BvaW50KGFlcyh0ZXh0ID0gcGFzdGUoIlNhbXBsZSBJRDoiLCBTYW1wbGVfSUQpKSwKICAgICAgICAgICAgIHBvc2l0aW9uPSdqaXR0ZXInLHNpemU9MykrCiAgeGxhYigiXG5EYXkgb2YgR2VzdGF0aW9uXG4iKSArICMgWCBheGlzIGxhYmVsCiAgeWxhYigiXG5FeG9zb21lcy9tbFxuIikgKyAjIFkgYXhpcyBsYWJlbAogIGdndGl0bGUoIlBsYXNtYSBFeG9zb21lIENvbmNlbnRyYXRpb25cblRocm91Z2hvdXQgUHJlZ25hbmN5XG4iKSsgI3RpdGxlCiAgbGFicyhjb2xvcj0iQ29uZGl0aW9uIikrICMgTGFiZWwgdGFibGUgdGl0bGUKICBzY2FsZV94X2Rpc2NyZXRlKGJyZWFrcz1jKCIxIiwiNSIsIjEwIiwiMTQiLCIxNyIsIjIwIiksICAjIENoYW5nZSBYIGF4aXMgbGFiZWwKICAgICAgICAgICAgICAgICAgIGxhYmVscz1jKCJWaXJnaW4iLCI1IiwiMTAiLCIxNCIsIjE3IiwiMSBEYXkgUG9zdCIpKSArCiAgc2NhbGVfY29sb3JfZGlzY3JldGUobGFiZWxzPWMoIlZpcmdpbiIsIjUiLCIxMCIsIjE0IiwiMTciLCIxIERheSBQb3N0IikpICMgQ2hhbmdlIExlZ2VuZAogIApwbG90MQoKI2dnc2F2ZSgiRXhvc29tZV9wbG90LnBuZyIsIGhlaWdodCA9IDUsIHdpZHRoID0gNywgdW5pdHMgPSAiaW4iLCBkcGkgPSA2MDApCgpgYGAKCiMjUGxvdGx5CmBgYHtyfQogIGdncGxvdGx5KHBsb3QxKQpgYGAKCgoKIyMjQmFyIHBsb3QKYGBge3IsIHdhcm5pbmc9RkFMU0V9CnBsb3QgPC0gdGVzdDQgJT4lIAogIGdncGxvdChhZXMoeD1EYXksIHk9RGF5X21lYW4sIGZpbGw9RGF5ICkpKyAjcGxvdAogIGdlb21fY29sKCkrCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1EYXlfbWVhbi1EYXlfc2UsIHltYXg9RGF5X21lYW4rRGF5X3NlKSwgd2lkdGg9LjUsIAogICAgICAgICAgICAgICAgc2l6ZT0wLjgsIGNvbG91cj0iYmxhY2siLCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSguOSkpICsgI2Vycm9yIGJhcnMKICBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kPWMoMCwwKSwgYnJlYWtzID0gc2VxKDFFMTEsNEUxMSwxRTExKSkrICNzZXQgYm90dG9tIG9mIGdyYXBoIGFuZCBzY2FsZQogIHhsYWIoIlxuRGF5IG9mIEdlc3RhdGlvblxuIikgKyAjIFggYXhpcyBsYWJlbAogIHlsYWIoIlxuRXhvc29tZXMvbWxcbiIpICsgIyBZIGF4aXMgbGFiZWwKICBnZ3RpdGxlKCJQbGFzbWEgRXhvc29tZSBDb25jZW50cmF0aW9uXG5UaHJvdWdob3V0IFByZWduYW5jeVxuIikrICN0aXRsZQogIGxhYnMoZmlsbD0iQ29uZGl0aW9uIikgKyAjIExhYmVsIHRhYmxlIHRpdGxlCiAgc2NhbGVfeF9kaXNjcmV0ZShicmVha3M9YygiMSIsIjUiLCIxMCIsIjE0IiwiMTciLCIyMCIpLCAgIyBDaGFuZ2UgWCBheGlzIGxhYmVsCiAgICAgICAgICAgICAgICAgICBsYWJlbHM9YygiVmlyZ2luIiwiNSIsIjEwIiwiMTQiLCIxNyIsIjEgRGF5IFBvc3QiKSkgKwogIHNjYWxlX2ZpbGxfZGlzY3JldGUobGFiZWxzPWMoIlZpcmdpbiIsIjUiLCIxMCIsIjE0IiwiMTciLCIxIERheSBQb3N0IikpCgpwbG90CgpnZ3NhdmUoIkV4b3NvbWVfYmFycGxvdC5wbmciLCBoZWlnaHQgPSA1LCB3aWR0aCA9IDcsIHVuaXRzID0gImluIiwgZHBpID0gNjAwKQpgYGAKCgojIyNMb29raW5nIGF0IFZhcmlhdGlvbiBiZXR3ZWVuIHRoZSBkYXlzIHRoZSBzYW1wbGVzIHdlcmUgcnVuCmBgYHtyLCB3YXJuaW5nPUZBTFNFfQp0ZXN0NyA8LSB0ZXN0MyAlPiUgCiAgbGVmdF9qb2luKHRjMSkKCnBsb3QyIDwtIHRlc3Q3ICU+JQogIGdncGxvdChhZXMoeCA9IERheSwgeSA9IHBhcnRpY2xlX2NvbmMsIGNvbG9yID0gRGF5LCBzaGFwZT1URUlfRGF5KSkrCiAgZ2VvbV9wb2ludChwb3NpdGlvbj0gJ2RvZGdlJyxzaXplPTQpKwogIHNjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXM9YygxNSwxNiwxNywxOCwyMiwyMywyNCkpKwogIHhsYWIoIlxuRGF5IG9mIEdlc3RhdGlvblxuIikgKyAjIFggYXhpcyBsYWJlbAogIHlsYWIoIlxuRXhvc29tZXMvbWxcbiIpICsgIyBZIGF4aXMgbGFiZWwKICBnZ3RpdGxlKCJQbGFzbWEgRXhvc29tZSBDb25jZW50cmF0aW9uXG5UaHJvdWdob3V0IFByZWduYW5jeVxuIikrICN0aXRsZQogIGxhYnMoY29sb3I9IkNvbmRpdGlvbiIpICsgIyBMYWJlbCB0YWJsZSB0aXRsZQogIHNjYWxlX3hfZGlzY3JldGUoYnJlYWtzPWMoIjEiLCI1IiwiMTAiLCIxNCIsIjE3IiwiMjAiKSwgICMgQ2hhbmdlIFggYXhpcyBsYWJlbAogICAgICAgICAgICAgICAgICAgbGFiZWxzPWMoIlZpcmdpbiIsIjUiLCIxMCIsIjE0IiwiMTciLCIxIERheSBQb3N0IikpICsKICBzY2FsZV9jb2xvcl9kaXNjcmV0ZShsYWJlbHM9YygiVmlyZ2luIiwiNSIsIjEwIiwiMTQiLCIxNyIsIjEgRGF5IFBvc3QiKSkKCnBsb3QyCgpgYGAKCmBgYHtyfQpnZ3Bsb3RseShwbG90MikKYGBgCgojTG9va2luZyBhdCBuYW5vcGFydGljbGUgcmFuZ2UKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9Cm5hbm9fMTAwIDwtIGRhdGE0ICU+JSAKICBmaWx0ZXIocGFydGljbGVfc2l6ZTwxNDAuNSkKCm5hbm9fMTAwX2RhdGEgPC0gbGVmdF9qb2luKHRjMSxuYW5vXzEwMCwgYnk9ICJTYW1wbGVfSUQiKQoKbmFub18xMDBfZGF0YV9wbG90IDwtIG5hbm9fMTAwX2RhdGEgJT4lCiAgZ3JvdXBfYnkoRGF5LFNhbXBsZV9JRCkgJT4lIAogIHN1bW1hcmlzZShwYXJ0aWNsZV9jb25jPXN1bShpbmpfbWVhbikpICU+JSAKICBmaWx0ZXIoIVNhbXBsZV9JRCAlaW4lIGMoJzYnLCcyOCcsJzMyJykpICU+JSAKICBnZ3Bsb3QoYWVzKGZhY3RvcihEYXkpLHBhcnRpY2xlX2NvbmMsIGNvbG9yPURheSkpICsKICBnZW9tX2JveHBsb3QoY29sb3VyPSJibGFjayIsZmlsbD1OQSkgKyAKICBnZW9tX3BvaW50KHBvc2l0aW9uPSdqaXR0ZXInLHNpemU9MykrCiAgeGxhYigiXG5EYXkgb2YgR2VzdGF0aW9uXG4iKSArICMgWCBheGlzIGxhYmVsCiAgeWxhYigiXG5FeG9zb21lcy9tbFxuIikgKyAjIFkgYXhpcyBsYWJlbAogIGdndGl0bGUoIlBsYXNtYSBFeG9zb21lIENvbmNlbnRyYXRpb25cblRocm91Z2hvdXQgUHJlZ25hbmN5XG4iKSsgI3RpdGxlCiAgbGFicyhjb2xvcj0iQ29uZGl0aW9uIikgKyAjIExhYmVsIHRhYmxlIHRpdGxlCiAgc2NhbGVfeF9kaXNjcmV0ZShicmVha3M9YygiMSIsIjUiLCIxMCIsIjE0IiwiMTciLCIyMCIpLCAgIyBDaGFuZ2UgWCBheGlzIGxhYmVsCiAgICAgICAgICAgICAgICAgICBsYWJlbHM9YygiVmlyZ2luIiwiNSIsIjEwIiwiMTQiLCIxNyIsIjEgRGF5IFBvc3QiKSkgKwogIHNjYWxlX2NvbG9yX2Rpc2NyZXRlKGxhYmVscz1jKCJWaXJnaW4iLCI1IiwiMTAiLCIxNCIsIjE3IiwiMSBEYXkgUG9zdCIpKQoKbmFub18xMDBfZGF0YV9wbG90ICAgCiAgCgpgYGAKCiNTdGF0aXN0aWNzCgoKIyMjU2hhcGlybyB0ZXN0CmBgYHtyfQp0aWR5KHNoYXBpcm8udGVzdCh0ZXN0MyRwYXJ0aWNsZV9jb25jKSkKCmBgYApwIHZhbHVlID4wLjA1IHRoZXJlZm9yZSBjb25sdWRlIGRhdGEgaXMgbm9ybWFsbHkgZGlzdHJpYnV0ZWQKCiMjI0FOT1ZBCmBgYHtyfQoKamFjb2IgPC0gbmFub18xMDBfZGF0YSAlPiUKICAgZ3JvdXBfYnkoRGF5LFNhbXBsZV9JRCkgJT4lIAogIHN1bW1hcmlzZShwYXJ0aWNsZV9jb25jPXN1bShpbmpfbWVhbikpICU+JSAKICBmaWx0ZXIoIVNhbXBsZV9JRCAlaW4lIGMoJzYnLCcyOCcsJzMyJykpCiAgICAgICAgIApmaXQgPC0gYW92KHBhcnRpY2xlX2NvbmMgfiBEYXksIGRhdGE9amFjb2IpCnN0YXRzIDwtIHRpZHkoZml0KQpzdGF0cwpgYGAKU3RhdGlzdGljYWxseSBzaWduaWZpY2FudCwgdGh1cyBUdWtleSdzIEhTRCBwb3N0IGhvYyBhbmFseXNpcyBjYW4gZGV0ZXJtaW5lIHNpZ25pZmljYW50IGRpZmZlcmVuY2VzLgoKIyMjVHVrZXkgUG9zdCBIb2MgVGVzdApgYGB7cn0KSFNEIDwtIFR1a2V5SFNEKGZpdCkKdHVrZXkgPC0gdGlkeShIU0QpCnR1a2V5CmBgYAoKIyMjU2lnbmlmaWNhbnQgVHVrZXkgUG9zdCBIb2MgVGVzdCBWYWx1ZXMKYGBge3J9CnR1a2V5ICU+JQogIGZpbHRlcihhZGoucC52YWx1ZTwwLjA1KSAlPiUgCiAgYXJyYW5nZShhZGoucC52YWx1ZSkKYGBgCgoKCgoKCmBgYHtyfQp0ZXN0OCA8LSB0ZXN0NyAlPiUgCiAgZmlsdGVyKCFEYXkgPT0gIjIwIikKCmZpdCA8LSBsbShwYXJ0aWNsZV9jb25jIH4gV2VpZ2h0ICxkYXRhID0gdGVzdDgpCgpzdW1tYXJ5KGZpdCkKdGlkeShzdW1tYXJ5KGZpdCkpCgoKYGBgCgpgYGB7cn0KdGVzdDcgJT4lIAogIGdncGxvdChhZXMoeD0gV2VpZ2h0LCB5ID0gcGFydGljbGVfY29uYykpKwogIGdlb21fcG9pbnQoKSsKICBnZW9tX3Ntb290aCgpKwogIHhsYWIoIlxuV2VpZ2h0IChnKVxuIikgKyAjIFggYXhpcyBsYWJlbAogIHlsYWIoIkV4b3NvbWVzL21sXG4iKSArICMgWSBheGlzIGxhYmVsCiAgZ2d0aXRsZSgiTGluZWFyIFJlZ3Jlc3Npb24gb2YgRXhvc29tZSBcbkNvbmNlbnRyYXRpb24gdnMuIFdlaWdodCIpKyAjdGl0bGUKICBsYWJzKGNvbG9yPSJEYXkiKSNMYWJlbCB0YWJsZSB0aXRsZQoKICAKYGBgCmBgYHtyfQp0ZXN0NyAlPiUgCiAgZmlsdGVyKCFTYW1wbGVfSUQgPT0gJzcwJykgJT4lIAogIGdncGxvdChhZXMoeD0gV2VpZ2h0LCB5ID0gcGFydGljbGVfY29uYykpKwogIGdlb21fcG9pbnQoc2l6ZSA9IDMsYWVzKGNvbG9yPWZhY3RvcihEYXkpKSkrCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgbGV2ZWwgPSAwLjk1KSsKICB4bGFiKCJcbldlaWdodCAoZylcbiIpICsgIyBYIGF4aXMgbGFiZWwKICB5bGFiKCJFeG9zb21lcy9tbFxuIikgKyAjIFkgYXhpcyBsYWJlbAogIGdndGl0bGUoIkxpbmVhciBSZWdyZXNzaW9uIG9mIEV4b3NvbWUgXG5Db25jZW50cmF0aW9uIHZzLiBXZWlnaHQiKSsgI3RpdGxlCiAgbGFicyhjb2xvcj0iRGF5IikjTGFiZWwgdGFibGUgdGl0bGUKCmBgYAoKCmBgYHtyfQp0ZXN0NyAlPiUgCiAgZ2dwbG90KGFlcyh4PSBQdXBzLCB5ID0gcGFydGljbGVfY29uYykpKwogIGdlb21fcG9pbnQoc2l6ZSA9IDQsIGFlcyhjb2xvcj1mYWN0b3IoRGF5KSkpKwogICNnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBsZXZlbCA9IDAuOTUpKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3M9c2VxKDAsMTIsMikpKwogIHhsYWIoIlxuTnVtYndlIG9mIFB1cHNcbiIpICsgIyBYIGF4aXMgbGFiZWwKICB5bGFiKCJFeG9zb21lcy9tbFxuIikgKyAjIFkgYXhpcyBsYWJlbAogIGdndGl0bGUoIkxpbmVhciBSZWdyZXNzaW9uIG9mIEV4b3NvbWUgXG5Db25jZW50cmF0aW9uIHZzLiBOdW1iZXIgb2YgUHVwcyIpKyAjdGl0bGUKICBsYWJzKGNvbG9yPSJEYXkiKSNMYWJlbCB0YWJsZSB0aXRsZQpgYGAKCmBgYHtyfQptZWFuX3BsYWNlbnRhIDwtIHRjICU+JSAKICBmaWx0ZXIoRGF5ICVpbiUgYygnMTAnLCcxNCcsJzE3JykgJiAhU2FtcGxlX0lEICVpbiUgYygnNzAnLCc3MycsJzc0JywnNzUnKSkgJT4lCiAgc2VsZWN0KC0oVEVJX0RheTpQdXBfcmlnaHQpLC1SZXNvcnApICU+JSAKICBnYXRoZXIoIlBsYWNlbnRhX2F2ZyIsIlBsYWNfd2VpZ2h0IiwgMzo1KSAlPiUKICBncm91cF9ieShEYXksU2FtcGxlX0lEKSAlPiUgCiAgc3VtbWFyaXNlKE4gPSBsZW5ndGgoUGxhY193ZWlnaHQpLAogICAgICAgICAgICBtZWFuX3BsYWMgPSBtZWFuKFBsYWNfd2VpZ2h0KjEwMDAsIG5hLnJtID0gVFJVRSksICNjb252ZXJ0IGcgdG8gbWcKICAgICAgICAgICAgc2QgPSBzZChQbGFjX3dlaWdodCkqMTAwMCwgICNjb252ZXJ0IGcgdG8gbWcKICAgICAgICAgICAgc2UgPSBzZC9zcXJ0KE4pKQoKbWVhbl9wbGFjZW50YSAlPiUgCiAgaW5uZXJfam9pbih0ZXN0NykgJT4lIAogIGdncGxvdChhZXMoeD0gbWVhbl9wbGFjLCB5ID0gcGFydGljbGVfY29uYykpKwogIGdlb21fcG9pbnQoc2l6ZT0gMyxhZXMoY29sb3I9ZmFjdG9yKERheSkpKSsKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBsZXZlbCA9IDAuOTUpKwogIHhsYWIoIlxuUGxhY2VudGFsIFdlaWdodCAobWcpXG4iKSArICMgWCBheGlzIGxhYmVsCiAgeWxhYigiXG5FeG9zb21lcy9tbFxuIikgKyAjIFkgYXhpcyBsYWJlbAogIGdndGl0bGUoIlBsYXNtYSBFeG9zb21lIENvbmNlbnRyYXRpb25cblRocm91Z2hvdXQgUHJlZ25hbmN5XG4iKSsgI3RpdGxlCiAgbGFicyhjb2xvcj0iRy5ELiIpI0xhYmVsIHRhYmxlIHRpdGxlCgpgYGAKCgpgYGB7cn0KbWVhbl9wbGFjZW50YSAlPiUgCiAgaW5uZXJfam9pbih0ZXN0NykgJT4lIAogIGdncGxvdChhZXMoeCA9IFB1cHMsIHkgPSBwYXJ0aWNsZV9jb25jKSkrCiAgZ2VvbV9wb2ludChzaXplPSAzLGFlcyhjb2xvcj1mYWN0b3IoRGF5KSkpKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlPSBGQUxTRSkrCiAgZmFjZXRfd3JhcCh+RGF5KSsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgxLDEyLDIpKSsKICB4bGFiKCJcbk51bWJyIG9mIFB1cHNcbiIpICsgIyBYIGF4aXMgbGFiZWwKICB5bGFiKCJcbkV4b3NvbWVzL21sXG4iKSArICMgWSBheGlzIGxhYmVsCiAgZ2d0aXRsZSgiUGxhc21hIEV4b3NvbWUgQ29uY2VudHJhdGlvblxuVGhyb3VnaG91dCBQcmVnbmFuY3lcbiIpKyAjdGl0bGUKICBsYWJzKGNvbG9yPSJHLkQuIikjTGFiZWwgdGFibGUgdGl0bGUKYGBgCgoKCmBgYHtyfQp0ZXN0MyAlPiUgCiAgZmlsdGVyKCFEYXkgJWluJSBjKCcxJywnMjAnKSkgJT4lIAogIGdyb3VwX2J5KERheSkgJT4lIAogIGdncGxvdChhZXMoZmFjdG9yKERheSkscGFydGljbGVfY29uYywgY29sb3I9RGF5KSkgKwogIGdlb21fcG9pbnQoc2l6ZT0zKSsKICB4bGFiKCJcbkRheSBvZiBHZXN0YXRpb25cbiIpICsgIyBYIGF4aXMgbGFiZWwKICB5bGFiKCJcbkV4b3NvbWVzL21sXG4iKSArICMgWSBheGlzIGxhYmVsCiAgZ2d0aXRsZSgiUGxhc21hIEV4b3NvbWUgQ29uY2VudHJhdGlvblxuVGhyb3VnaG91dCBQcmVnbmFuY3lcbiIpKyAjdGl0bGUKICBsYWJzKGNvbG9yPSJDb25kaXRpb24iKSNMYWJlbCB0YWJsZSB0aXRsZQoKCmBgYAoKCgpgYGB7cn0KbmFub3NpZ2h0X3Bsb3QgPC0gdGVzdDEgJT4lCiAgZmlsdGVyKFNhbXBsZV9JRCA9PSAnNzUnKSAlPiUgCiAgZ2dwbG90KGFlcyh4PXBhcnRpY2xlX3NpemUsIHk9dGVjaF9tZWFuLGNvbG9yPUluamVjdGlvbiApKSsgI3Bsb3QKICBnZW9tX3JpYmJvbihhZXMoeW1pbj10ZWNoX21lYW4tdGVjaF9zZSwgeW1heD10ZWNoX21lYW4rdGVjaF9zZSksYWxwaGE9MC4yLGZpbGwgPSBhbHBoYSgnZ3JleTEyJywgMC4yKSkgKyAjZXJyb3IgYmFycwogIGdlb21fbGluZShzaXplPTEuMCkgKyB4bGltKDAsNTAwKSsgI2xpbmUgc2l6ZSwgeC1heGlzIHNjYWxlCiAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZD1jKDAsMCkpKyAjc2V0IGJvdHRvbSBvZiBncmFwaAogIHhsYWIoIlBhcnRpY2xlIFNpemUgKG5tKSIpICsgIyBYIGF4aXMgbGFiZWwKICB5bGFiKCJcbk1lYW4gUGFydGljbGUgQ29uY2VudHJhdGlvbi9tbFxuIikgKyAjIFkgYXhpcyBsYWJlbAogIGdndGl0bGUoIk5hbm9zaWdodCBIaXN0b2dyYW0gb2ZcblZpcmdpbiBNb3VzZSBQbGFzbWEiKSsgI3RpdGxlCiAgbGFicyhjb2xvcj0iSW5qZWN0aW9uIikrICNMYWJlbCB0YWJsZSB0aXRsZQogIGZhY2V0X3dyYXAoIH5JbmplY3Rpb24pCgpuYW5vc2lnaHRfcGxvdAoKZ2dzYXZlKCJOYW5vc2lnaHRfcGxvdC5wbmciLCBoZWlnaHQgPSA1LCB3aWR0aCA9IDcsIHVuaXRzID0gImluIiwgZHBpID0gNjAwKQpgYGAKCg==